﻿using BadOCR.Common;
using BadOCR.Runtime;
using BadOCR.View;
using PInvoke;
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace BadOCR
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainView : Window
    {
        private ClipboardMonitor _monitor;
        private const Int32 MY_HOTKEYID_OCR = 0x9998;
        
        public MainView()
        {
            InitializeComponent();

            DataContext = this;
        }

        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);

            // 注册热键
            IntPtr handle = new WindowInteropHelper(this).Handle;
            // https://docs.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-registerhotkey?redirectedfrom=MSDN
            RegisterHotKey(handle, MY_HOTKEYID_OCR, 0x0002, 0x51);  // Ctrl + Q

            // Hook当前窗口的消息(OnSourceInitialized之后, HwndSource才不为空)
            HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
            source.AddHook(WndProc);

            // 监控剪贴板
            var windowHandle = new WindowInteropHelper(this).EnsureHandle();
            _monitor = new ClipboardMonitor(windowHandle);
            _monitor.OnClipboardUpdated += _monitor_OnClipboardUpdated;
        }

        IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handle)
        {
            if (wParam.ToInt32() == MY_HOTKEYID_OCR)
            {
                HandleAsync();
            }

            return IntPtr.Zero;
        }

        public async void HandleAsync()
        {
            var screenshotText = await OCRUserControl.OCRScreenshot();
            if (string.IsNullOrEmpty(screenshotText))
                return;

            var selectedMenuItemName = MenuItems[SelectedMenuItemIndex].Name;
            if (selectedMenuItemName == "OCR")
            {
                OCRUserControl.Text = screenshotText;

                if (UserConfig.Current.AutoSave)
                    ClipboardHelper.SetText(screenshotText);
            }
            else if (selectedMenuItemName == "Translate")
            {
                TranslateUserControl.Translate(screenshotText);
            }
            else if (selectedMenuItemName == "Search")
            {
                SearchUserControl.Search(screenshotText);
            }
        }

        #region BindingProperty
        public List<MainViewMenuItem> MenuItems => new List<MainViewMenuItem>{
            new MainViewMenuItem("OCR", "文字识别", "../Resources/OCR1.png", "../Resources/OCR2.png", 32),
            new MainViewMenuItem("Translate", "翻译", "../Resources/Translate1.png", "../Resources/Translate2.png", 32),
            new MainViewMenuItem("Search", "搜索", "../Resources/Search1.png", "../Resources/Search2.png", 32)
        };
        public byte SelectedMenuItemIndex { get; set; }
        #endregion

        private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.RemovedItems.Count == 0)
                return;

            //e.Handled = true;
            var previousMenuItem = e.RemovedItems[0] as MainViewMenuItem;

            var menuItem = e.AddedItems[0] as MainViewMenuItem;
            if (menuItem.Name == "OCR")
            {
                OCRUserControl.Visibility = Visibility.Visible;
                SearchUserControl.Visibility = Visibility.Hidden;
                TranslateUserControl.Visibility = Visibility.Hidden;

                this.Width = 450;
                this.Height = 350;

                Thread.Sleep(100);  // WindowState状态变化似乎会影响ListBox_SelectionChanged错误
                this.WindowState = WindowState.Normal;
                //User32.ShowWindow(new WindowInteropHelper(this).Handle, User32.WindowShowStyle.SW_SHOWNORMAL);
            }
            else if (menuItem.Name == "Translate")
            {
                OCRUserControl.Visibility = Visibility.Hidden;
                SearchUserControl.Visibility = Visibility.Hidden;
                TranslateUserControl.Visibility = Visibility.Visible;

                this.Width = 350;
                this.Height = 550;

                Thread.Sleep(100);
                this.WindowState = WindowState.Normal;
                //User32.ShowWindow(new WindowInteropHelper(this).Handle, User32.WindowShowStyle.SW_SHOWNORMAL);

                if (previousMenuItem.Name == "OCR")
                {
                    var ocrText = OCRUserControl.Text.Trim();
                    TranslateUserControl.Translate(ocrText);
                }
            }
            else if (menuItem.Name == "Search")
            {
                OCRUserControl.Visibility = Visibility.Hidden;
                SearchUserControl.Visibility = Visibility.Visible;
                TranslateUserControl.Visibility = Visibility.Hidden;

                Thread.Sleep(100);
                this.WindowState = WindowState.Maximized;
                //User32.ShowWindow(new WindowInteropHelper(this).Handle, User32.WindowShowStyle.SW_SHOWMAXIMIZED);

                if (previousMenuItem.Name == "OCR")
                {
                    var ocrText = OCRUserControl.Text.Trim();
                    if(!string.IsNullOrEmpty(ocrText))
                        SearchUserControl.Search(ocrText);
                }
            }
        }

        private void _monitor_OnClipboardUpdated(object sender, ClipboardUpdateEventArgs e)
        {
            if (e.Kind == ClipboardContentKind.Text)
            {
                if(SelectedMenuItemIndex == 1 && TranslateUserControl.MonitorClipboard)
                    TranslateUserControl.Translate(e.Text?.Trim());
            }
        }

        #region PInvoke
        [DllImport("user32.dll")]
        public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
        #endregion
    }
}
